<template>
  <view class="publish-container">
    <uni-forms ref="publishRef" :model="publishForm" :rules="publishRules">
      <uni-forms-item name="images">
        <uni-file-picker
          limit="6"
          title="最多选择6张图片"
          fileMediatype="image"
          @select="publishImageSelect"
          @delete="publishImageDelete"
          v-model="publishForm.images"
        ></uni-file-picker>
      </uni-forms-item>
      <uni-forms-item label="投票标题:" name="tittle" label-width="85">
        <uni-easyinput
          type="text"
          v-model="publishForm.tittle"
          placeholder="请输入投票标题"
        ></uni-easyinput>
      </uni-forms-item>
      <uni-forms-item label="投票内容:" name="intro" label-width="85">
        <uni-easyinput
          type="textarea"
          v-model="publishForm.intro"
          placeholder="请输入投票内容"
        ></uni-easyinput>
      </uni-forms-item>
      <uni-forms-item label="投票类型:" name="genre" label-width="85">
        <uni-data-select
          v-model="publishForm.genre"
          :localdata="typeRange"
          placeholder="请选择投票类型"
        ></uni-data-select>
      </uni-forms-item>
      <uni-forms-item label="时间范围:" name="datetimerange" label-width="85">
        <uni-datetime-picker
          v-model="publishForm.datetimerange"
          type="datetimerange"
          rangeSeparator="至"
        />
      </uni-forms-item>
      <uni-forms-item name="players" label-width="85">
        <text class="label-title">参赛选手:</text>
        <view
          class="player-item"
          v-for="(player, index) in publishForm.list"
          :key="index"
        >
          <image :src="player.images[0].url" class="player-img" />
          <view class="player-info">
            <text class="player-name">{{ player.tittle }}</text>
            <text class="player-desc">{{ player.intro }}</text>
            <view class="player-btn-container">
              <button
                class="player-btn"
                type="primary"
                size="mini"
                @tap="playerEdit(index)"
              >
                编辑
              </button>
              <button
                class="player-btn"
                type="warn"
                size="mini"
                @tap="playerDelete(index)"
              >
                移除
              </button>
            </view>
          </view>
        </view>
        <button class="add-player-btn" @click="toggle()">添加选手</button>
      </uni-forms-item>
      <view class="form-btn-container">
        <button @click="voteSubmit(false)" class="submit-btn save-draft">
          存草稿
        </button>
        <button @click="voteSubmit(true)" class="submit-btn publish-btn">
          发布
        </button>
      </view>
    </uni-forms>
    <view>
      <!-- 普通弹窗 -->
      <uni-popup ref="popup" background-color="#fff" type="bottom">
        <view class="player-container">
          <uni-forms ref="playerRef" :model="playerForm" :rules="playerRules">
            <uni-forms-item name="images">
              <uni-file-picker
                limit="1"
                title="最多选择1张图片"
                fileMediatype="image"
                @select="playerImageSelect"
                @delete="playerImagesDelete"
                v-model="playerForm.images"
                return-type="array"
              ></uni-file-picker>
            </uni-forms-item>
            <uni-forms-item label="选手名称:" name="tittle" label-width="85">
              <uni-easyinput
                type="text"
                v-model="playerForm.tittle"
                placeholder="请输入投票标题"
              ></uni-easyinput>
            </uni-forms-item>
            <uni-forms-item label="选手描述:" name="intro" label-width="85">
              <uni-easyinput
                type="textarea"
                v-model="playerForm.intro"
                placeholder="请输入选手描述"
              ></uni-easyinput>
            </uni-forms-item>
            <view class="form-btn-container">
              <button @click="playerSubmit" class="submit-btn">
                {{ isEdit ? "修改" : "添加" }}选手
              </button>
            </view>
          </uni-forms>
        </view>
      </uni-popup>
    </view>
  </view>
</template>

<script setup lang="ts">
import {
  playerType,
  publishVoteParamsType,
  PublishState,
  imageType,
} from "@/types/vote";
import { uploadFileAPI } from "@/api/file";
import { postPublishVoteAPI } from "@/api/vote";
import { reactive, ref } from "vue";
import { strToTimestamp } from "@/utils/time";

const popup = ref<UniHelper.UniPopupInstance>();

const isEdit = ref(false);
const playerIndex = ref(0);

//打开添加弹窗
const toggle = () => {
  isEdit.value = false;
  resetPlayerForm();
  popup.value?.open?.();
};

//类型选项
const typeRange = [
  { text: "生活", value: "life" },
  { text: "教育", value: "education" },
  { text: "科技", value: "tech" },
  { text: "互联网", value: "internet" },
];

const publishForm: publishVoteParamsType = reactive({
  list: [],
  tittle: "",
  intro: "",
  genre: "",
  datetimerange: [],
  startTime: "",
  endTime: "",
  images: [],
  cover: "",
  state: "",
});

const publishRules: UniHelper.UniFormsRules = {
  images: {
    rules: [{ required: true, errorMessage: "请上传投票活动图片" }],
  },
  tittle: {
    rules: [
      { required: true, errorMessage: "请输入投票标题" },
      { maxLength: 16, errorMessage: "投票标题不能超过16个字符" },
    ],
  },
  intro: {
    rules: [
      { required: true, errorMessage: "请输入投票内容" },
      { maxLength: 100, errorMessage: "投票内容不能超过100个字符" },
    ],
  },
  genre: {
    rules: [{ required: true, errorMessage: "请选择投票类型" }],
  },
  datetimerange: {
    rules: [{ required: true, errorMessage: "请选择时间范围" }],
  },
};

const publishRef = ref<UniHelper.UniFormsInstance>();

//选手表单
const playerForm: playerType = reactive({
  images: [],
  cover: "",
  tittle: "",
  state: PublishState.approved,
  intro: "",
});
const playerRules: UniHelper.UniFormsRules = {
  images: {
    rules: [{ required: true, errorMessage: "请上传选手图片" }],
  },
  tittle: {
    rules: [
      { required: true, errorMessage: "请输入选手名称" },
      { maxLength: 16, errorMessage: "选手名称不能超过16个字符" },
    ],
  },
  intro: {
    rules: [
      {
        required: true,
        errorMessage: "请输入选手描述",
      },
      { maxLength: 100, errorMessage: "选手描述不能超过100个字符" },
    ],
  },
};
const playerRef = ref<UniHelper.UniFormsInstance>();

const playerSubmit = async () => {
  await playerRef.value?.validate?.();
  if (isEdit.value) {
    publishForm.list[playerIndex.value].images = playerForm.images;
    publishForm.list[playerIndex.value].tittle = playerForm.tittle;
    publishForm.list[playerIndex.value].intro = playerForm.intro;
  } else {
    const playerData = JSON.parse(JSON.stringify(playerForm));
    publishForm.list.push(playerData);
  }
  popup.value?.close?.();
};

//重置表单
const resetPublishForm = () => {
  publishForm.images = [];
  publishForm.tittle = "";
  publishForm.intro = "";
  publishForm.state = "";
  publishForm.datetimerange = [];
  publishForm.genre = "";
  publishForm.list = [];
  publishForm.cover = "";
  publishForm.startTime = "";
  publishForm.endTime = "";
};

//重置选手表单
const resetPlayerForm = () => {
  playerForm.images = [];
  playerForm.tittle = "";
  playerForm.intro = "";
  playerForm.cover = "";
};

const voteSubmit = async (isPublish: boolean) => {
  publishRef.value?.validate?.();
  publishForm.startTime = strToTimestamp(publishForm.datetimerange[0]);
  publishForm.endTime = strToTimestamp(publishForm.datetimerange[1]);
  publishForm.state = isPublish ? PublishState.pending : PublishState.editing;
  await voteUploadFile(publishForm.images);
  await playerUploadFile(publishForm.list);
  await postPublishVoteAPI(publishForm);
  resetPublishForm();
  uni.showToast({
    title: `${isPublish ? "发布" : "存草稿"}成功`,
    icon: "success",
    duration: 1000,
  });
};

const voteUploadFile = async (imageList: imageType[]) => {
  const uploadPromises = imageList.map((item) => uploadFileAPI(item));

  try {
    const responses = await Promise.all(uploadPromises);
    const fileUrlList = responses.flatMap((res) => res.data.fileUrl);
    publishForm.cover = fileUrlList.join(","); // 使用 join 代替 toString
  } catch (error) {
    console.error("上传文件时发生错误：", error);
    // 处理错误的逻辑，比如显示提示信息等
  }
};

//选手上传文件(上传每个选手的多个image，并将放回的url存入对应的选手cover)
const playerUploadFile = async (playerList: playerType[]) => {
  // 对每个选手，上传他们的图片并收集返回的 Promise
  const uploadPromises = playerList.map(async (item, index) => {
    // 上传每个选手的所有图片
    const imagePromises = item.images.map((image) => uploadFileAPI(image));
    // 等待所有图片上传完成，并获取结果
    const imageUrls = await Promise.all(imagePromises);
    // 提取每个上传结果的 fileUrl
    const coverUrls = imageUrls.map((response) => response.data.fileUrl);
    // 将这些 URL 合并成一个逗号分隔的字符串
    const cover = coverUrls.join(",");
    // 更新选手的 cover 属性
    playerList[index].cover = cover;
  });

  try {
    // 等待所有选手的图片上传处理完成
    await Promise.all(uploadPromises);
  } catch (error) {
    console.error("上传文件时发生错误：", error);
    // 处理错误的逻辑，比如显示提示信息等
    uni.showToast({
      title: "上传图片失败",
      icon: "error",
      duration: 1000,
    });
  }
};

//投票图片
const publishImageSelect: UniHelper.UniFilePickerOnSelect = (event) => {
  const imageDatas = event.tempFiles.map((item: any) => {
    return { url: item.url, name: item.name };
  });
  publishForm.images.push(...imageDatas);
};

const publishImageDelete: UniHelper.UniFilePickerOnDelete = (event: any) => {
  publishForm.images.splice(event.index, 1);
};

//选手
const playerImageSelect: UniHelper.UniFilePickerOnSelect = (event: any) => {
  const imageDatas = event.tempFiles.map((item: any) => {
    return { url: item.url, name: item.name };
  });
  playerForm.images.push(...imageDatas);
};

const playerImagesDelete: UniHelper.UniFilePickerOnDelete = (event: any) => {
  playerForm.images.splice(event.index, 1);
};

//编辑选手
const playerEdit = (index: number) => {
  isEdit.value = true;
  playerIndex.value = index;
  playerForm.images = publishForm.list[index].images;
  playerForm.cover = publishForm.list[index].cover;
  playerForm.tittle = publishForm.list[index].tittle;
  playerForm.intro = publishForm.list[index].intro;
  popup.value?.open?.();
};

//删除选手
const playerDelete = (index: number) => {
  publishForm.list.splice(index, 1);
};
</script>

<style scoped lang="scss">
.player-item {
  display: flex;
  margin: 10rpx 0;
  padding: 20rpx;
  border-radius: 12rpx;
  background-color: #fff;
  box-shadow: 2px 2px 4px rgba(0, 0, 0, 0.1);
  border: 1px solid #ebeef5;
  .player-img {
    width: 200rpx;
    height: 200rpx;
  }
  .player-info {
    flex-grow: 1;
    margin-left: 20rpx;
    display: flex;
    flex-direction: column;
    justify-content: space-between;
    .player-name {
      font-size: 28rpx;
      font-weight: bold;
      color: #333;
    }
    .player-desc {
      font-size: 24rpx;
      color: #666;
    }
    .player-btn-container {
      display: flex;
      justify-content: flex-end;
      .player-btn {
        margin: 0 10rpx;
      }
    }
  }
}

.label-title {
  text-align: left;
  font-size: 14px;
  color: #606266;
}

.add-player-btn {
  width: 500rpx;
  background-color: #2979ff;
  color: #fff;
  font-size: 28rpx;
  border-radius: 10rpx;
  margin: 20rpx auto 0;
  cursor: pointer;
  text-align: center;
}

.publish-container {
  padding: 20px;
  .form-btn-container {
    display: flex;
    justify-content: space-between;

    .submit-btn {
      display: flex;
      align-items: center;
      justify-content: center;
      width: 46%;
      height: 80rpx;
      font-size: 28rpx;
      border-radius: 8rpx;
    }

    .save-draft {
      background-color: #fff;
      color: #28bb9c;
      border: #28bb9c 1px solid;
    }

    .publish-btn {
      background-color: #28bb9c;
      color: #fff;
    }
  }
}

.player-container {
  padding: 20px;
  .form-btn-container {
    display: flex;
    justify-content: space-between;

    .submit-btn {
      display: flex;
      align-items: center;
      justify-content: center;
      width: 500rpx;
      background-color: #2979ff;
      height: 80rpx;
      font-size: 28rpx;
      border-radius: 8rpx;
      color: #fff;
    }
  }
}
</style>
